package com.zf.canal.config;

import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.zf.canal.annotation.Table;
import com.zf.canal.handler.RowDataHandler;
import com.zf.canal.utils.TableHelper;
import com.zf.canal.utils.TableInfo;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.InetSocketAddress;
import java.util.Map;

/**
 * canal的配置
 *
 * @author Zhou Feng
 */
@Configuration
public class CanalConfig implements InitializingBean {
    @Autowired
    private ApplicationContext ac;

    /**
     * 创建 连接单个Canal服务 的连接器
     */
    @Bean
    public CanalConnector canalConnector(CanalConnectProperties connectProperty) {
        // destination 表示连接到canal的哪个实例上，默认启动的实例名为 example
        //  username和password 是连接canal的用户名密码，默认没有用户名和密码，可随便填写，
        return CanalConnectors.newSingleConnector(
                new InetSocketAddress(connectProperty.getHost(), connectProperty.getPort()),
                connectProperty.getDestination(),
                connectProperty.getUsername(),
                connectProperty.getPassword()
        );
    }

    /**
     * 利用 spring 来自动构建TableHelper中的数据
     */
    @Override
    public void afterPropertiesSet() {
        // 获取所有的 RowDataHandler 对象
        Map<String, RowDataHandler> beansMaps = ac.getBeansOfType(RowDataHandler.class);
        if (MapUtils.isEmpty(beansMaps)) {
            return;
        }
        for (RowDataHandler rowDataHandler : beansMaps.values()) {
            // 实体类
            Class<?> entityClass = rowDataHandler.getEntityClass();
            // 默认将实体类名转为下划线形式来作为表名
            String tableName = StringUtils.uncapitalize(entityClass.getSimpleName())
                    .replaceAll("([A-Z])", "_$1")
                    .toLowerCase();
            Table tableAnnotation = entityClass.getAnnotation(Table.class);
            // 如果 实体类有table注解，且指定了表名，则取指定的表名
            if (tableAnnotation != null && StringUtils.isNotBlank(tableAnnotation.value())) {
                tableName = tableAnnotation.value();
            }
            TableInfo tableInfo = new TableInfo();
            tableInfo.setTableName(tableName);
            tableInfo.setHandler(rowDataHandler);
            tableInfo.setEntityClass(entityClass);
            TableHelper.addTableInfo(tableInfo);
        }
    }
}
